<!--
 * @Author: yanjikun
 * @Date: 2022-04-14 16:23:35
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-04-14 17:50:19
 * @Description: file content
-->
<template>
  <TreeSelect v-bind="getProps" :tree-data="getTreeData" @dropdown-visible-change="handleFetch">
    <template v-for="item in Object.keys($slots)" #[item]="data">
      <slot :name="item" v-bind="data ?? {}"></slot>
    </template>
    <template v-if="loading" #suffixIcon>
      <LoadingOutlined spin />
    </template>
    <template v-if="loading" #notFoundContent>
      <span>
        <LoadingOutlined spin class="mr-1" />
        请等待数据加载完成...
      </span>
    </template>
  </TreeSelect>
</template>

<script setup lang="ts">
import { computed, ref, unref, watch, watchEffect } from 'vue'
import { apiTreeSelectProps } from '../types/components'
import { TreeSelect } from 'ant-design-vue'
import { LoadingOutlined } from '@ant-design/icons-vue'
import { isArray, isFunction } from '@/utils/is'
import { listToTree } from '@/utils/helper/treeHelper'
defineOptions({
  name: 'ApiTreeSelect'
})
const props = defineProps(apiTreeSelectProps)
const emit = defineEmits(['tree-data-change', 'change'])
const loading = ref(false)
const isFirstLoad = ref(true)
const treeData = ref<Recordable[]>([])
const getProps = computed(() => props)
const getTreeData = computed(() => {
  return props.listToTree ? listToTree(unref(treeData)) : unref(treeData)
})
const fetch = async () => {
  const api = props.api
  if (!api || !isFunction(api)) return
  treeData.value = []
  try {
    loading.value = true
    const data = await api(props.params)
    if (isArray(data)) {
      treeData.value = data
      emitChange()
      return
    }
    if (props.resultField) {
      treeData.value = data?.[props.resultField] ?? []
    }
    emitChange()
  } catch (error) {
    console.warn(error)
  } finally {
    loading.value = false
  }
}
const handleFetch = async (visible) => {
  if (!visible) return
  if (props.alwaysLoad) {
    await fetch()
  } else if (!props.immediate && unref(isFirstLoad)) {
    await fetch()
    isFirstLoad.value = false
  }
}
const emitChange = () => {
  emit('tree-data-change', unref(getTreeData))
}
watchEffect(() => {
  props.immediate && !props.alwaysLoad && fetch()
})
watch(
  () => props.params,
  () => {
    !unref(isFirstLoad) && fetch()
  },
  { deep: true }
)
</script>

<style scoped lang="less"></style>
